import * as fs from 'fs';
import * as chalk from 'chalk';

// 清除控制台的一行文本
function clearCurrentLine() {
    process.stdout.write('\r')
    process.stdout.write('\u001b[K')
}
// 清除屏幕
function clear() {
    process.stdout.write('\u001b[2J\u001b[H');
}
// 输出彩色文本
function inputColorText(text) {
    process.stdout.write(chalk.green(text))
}
// 写入字符
function write(text) {
    process.stdout.write(text)
}

// 判断是否是文件
function isFile(path) {
    try {
        return fs.statSync(path).isFile()
    } catch (error) {
        return false;
    }
}

// 获取当前文件夹内所有文件和文件夹的路径列表
function getDirsAndFilesPath(path) {
    try {
        return fs.readdirSync(path)
    } catch (error) {
        return []
    }
}

/**
 * 手动调整 (全局依赖)
 * 
 * 注意：这里根据需要进行调整
 */
let watchPath = './demo'
// 存放所有符合条件的文件 (全局依赖)
let allFiles = []
// 需忽略的文件夹 (全局依赖)
let ignoreDirs = ['node_modules', 'layui', 'plugin']
// 需忽略的文件 (全局依赖)
let ignoreFiles = []
// 根据文件夹地址，获取所有文件 (全局依赖)
function getAllFilesByDirPath(path) {
    // 判断是否是文件夹
    if (!isFile(path)) {
        // 如果是文件夹，则判断当前文件夹是否在忽略列表中
        let strsTemp = path ? path.split('/') : []
        let nameTemp = '';
        if (strsTemp.length != 0) {
            nameTemp = strsTemp[strsTemp.length - 1]
        } else {
            nameTemp = path;
        }
        // 如果当前文件夹名称或文件名称 在忽略列表中不存在，则继续
        if (ignoreDirs.indexOf(nameTemp) == -1) {
            // 如果不存在，则获取当前文件夹中所有文件和文件夹路径
            let dirsFilesTemp = getDirsAndFilesPath(path)
            for (let dirfile of dirsFilesTemp) {
                // console.log(dirfile)
                let pathTemp = `${path}/${dirfile}`
                getAllFilesByDirPath(pathTemp)
            }
        }
    } else {
        // 如果该文件不在需忽略的文件中
        if (ignoreFiles.indexOf(path) == -1) {
            allFiles.push(path)
        }
    }
}

// 监听新增文件 如果出现新增文件，则重新运行该脚本
function watchNewFile(interval) {
    // 存放临时文件列表
    let beforeFileList = []
    let currentFileList = []

    let max_count = 10
    let waitStartChar = ''
    let waitChar = '.'
    let waitEndChar = ''
    // 持续获取当前文件列表的个数
    let count = -1;
    let intervalInstance = setInterval(async() => {
        count += 1
        if (count == 0) {
            write(waitStartChar)
        } else if (count == max_count) {
            write(waitEndChar)
        } else if (count > max_count) {
            clearCurrentLine()
            count = -1
        } else {
            // 输出.表示等待
            write(waitChar)
        }
        // 获取所有文件
        getAllFilesByDirPath(watchPath)
        // 如果之前文件列表的长度为0
        if (beforeFileList.length == 0 && currentFileList.length == 0) {
            // 对文件列表进行赋值
            allFiles.forEach((item) => {
                beforeFileList.push(item)
                currentFileList.push(item)
            })
        } else {
            // 对当前文件夹进行赋值
            allFiles.forEach((item) => {
                if (currentFileList.indexOf(item) == -1) {
                    currentFileList.push(item)
                }
            })
        }

        let beforeLength = beforeFileList.length
        let currentLength = currentFileList.length
        // write(`${beforeLength}, ${currentLength}`)
        if (beforeLength != currentLength) {
            if (currentLength - beforeLength > 0) {
                // 表示新增文件 则退出当前进程
                clearInterval(intervalInstance)
                // 遍历当前文件列表
                let list = currentFileList.filter(item => beforeFileList.indexOf(item) == -1)
                // 并将之前文件列表赋值
                beforeFileList = currentFileList
                write(`新增文件或文件夹${list.join(',')}\n`)
                // 遍历变化的路径
                for (let path of list) {
                    // 运行自定义脚本
                    await runScript(path, 'create')
                }
                // 退出当前进程
                process.exit()
            }
        }
    }, interval);
}

// 监听所有的文件的增删改查
function watchFileChange(interval, callback = (path, type) => { }) {
    allFiles.forEach(path => {
        fs.watchFile(path, { interval }, (curr, prev) => {
            if (Date.parse(curr.ctime) == 0) {
                callback(path, 'delete')
            } else if (Date.parse(curr.mtime) != Date.parse(curr, prev)) {
                callback(path, 'update')
            }
        })
    })
}

/**
 * 需要监听的路径
 * 
 * 注意：这里可以手动调整参数（注意：最上方的路径( watchPath 参数) 需根据使用情况进行更改）
 */
let watchNewFileInteval = 1000
let watchChangeInterval = 2000
// 导入自定义脚本
import { runScript } from './script.js'

// 获取所有文件
getAllFilesByDirPath(watchPath)

// 监听新增文件
watchNewFile(watchNewFileInteval)
// 输出当前监听的文件
write('\n当前监听的所有文件列表如下：\n')
write(`${allFiles.join(',\n')}`)
write('\n\n正在监听中:\n')

// 监听文件更改
let fileChangePath = ''
let fileChangeType = ''
watchFileChange(watchChangeInterval, (path, type) => {
    fileChangePath = path
    fileChangeType = type
})
// 根据返回的结果执行相应的操作
let watchFileChangeIntervalInstance = setInterval(async () => {
    if (fileChangeType == 'delete') {
        // 恢复默认值
        fileChangeType = ''
        fileChangePath = ''
        clearInterval(watchFileChangeIntervalInstance)
        // 运行自定义脚本
        await runScript(path, 'delete')
        write(`\n${path} 文件已删除 准备重新启动\n`)
        process.exit()
    } else if (fileChangeType == 'update') {
        let path = fileChangePath
        // 恢复默认值
        fileChangeType = ''
        fileChangePath = ''
        write(`\n${path} 文件已更新 启动自定义脚本\n`)
        // 运行自定义脚本
        await runScript(path, 'run')
    }
}, 1000);
